package com.ruoyi.workbench.service.impl;

import com.ruoyi.common.constant.DeptConstants;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.workbench.domain.PhysicalUnitImportTemplate;
import com.ruoyi.workbench.domain.WbCountyUnit;
import com.ruoyi.workbench.domain.WbPhysicalUnit;
import com.ruoyi.workbench.mapper.WbPhysicalUnitMapper;
import com.ruoyi.workbench.service.IWbPhysicalUnitService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author hanjiafeng
 */
@Slf4j
@Service
public class WbPhysicalUnitServiceImpl implements IWbPhysicalUnitService {
    private final WbPhysicalUnitMapper wbPhysicalUnitMapper;
    @Autowired
    private ISysDeptService sysDeptService;

    public WbPhysicalUnitServiceImpl(WbPhysicalUnitMapper wbPhysicalUnitMapper) {
        this.wbPhysicalUnitMapper = wbPhysicalUnitMapper;
    }

    @Override
    public int insertWbPhysicalUnit(WbPhysicalUnit wbPhysicalUnit) {
        wbPhysicalUnit.setCreateBy(ShiroUtils.getLoginName());
        wbPhysicalUnit.setCreateTime(new Date());
        return wbPhysicalUnitMapper.insertSelective(wbPhysicalUnit);
    }

    @Override
    public List<WbPhysicalUnit> selectWbPhysicalUnit(WbPhysicalUnit wbPhysicalUnit) {
        return wbPhysicalUnitMapper.selectWbPhysicalUnit(wbPhysicalUnit);
    }

    @Override
    public List<WbCountyUnit> selectWbCountyUnit(WbCountyUnit wbCountyUnit) {
        return wbPhysicalUnitMapper.selectWbCountyUnit6(wbCountyUnit);
    }

    @Override
    public WbPhysicalUnit selectByPrimaryKey(Long id) {
        return wbPhysicalUnitMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(WbPhysicalUnit record) {
        record.setUpdateBy(ShiroUtils.getLoginName());
        record.setUpdateTime(new Date());
        return wbPhysicalUnitMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int deleteByPrimaryKey(Long id) {
        WbPhysicalUnit w = new WbPhysicalUnit();
        w.setId(id);
        w.setDelFlag((byte) 2);
        return wbPhysicalUnitMapper.updateByPrimaryKeySelective(w);
    }

    @Override
    public List<WbPhysicalUnit> selectChildrenByParentId(Long parentId) {
        return wbPhysicalUnitMapper.selectChildrenById(parentId);
    }

    @Override
    public String importWbPhysicalUnit(List<PhysicalUnitImportTemplate> physicalUnitImportTemplateList) {
        if (StringUtils.isNull(physicalUnitImportTemplateList) || physicalUnitImportTemplateList.size() == 0) {
            throw new BusinessException("导入单元数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (PhysicalUnitImportTemplate physicalUnitImportTemplate : physicalUnitImportTemplateList) {
            //todo 校验该账号上传的行政村和下级单元是否符合本身权限
            try {
                String unitName = physicalUnitImportTemplate.getUnitName();
                Byte unitLevel = physicalUnitImportTemplate.getUnitLevel();
                String lastUnitName = physicalUnitImportTemplate.getLastUnitName();
                Long lastLastUnitId = physicalUnitImportTemplate.getLastLastUnitId();
                if (Objects.isNull(unitName)) {
                    throw new IllegalArgumentException("单元名称不能为空");
                } else if (Objects.isNull(unitLevel)) {
                    throw new IllegalArgumentException("单元等级不能为空");
                } else if (Objects.isNull(lastUnitName)) {
                    throw new IllegalArgumentException("上级单元名称不能为空");
                } else if (Objects.isNull(lastLastUnitId)) {
                    throw new IllegalArgumentException("上上级单元ID不能为空");
                }
                Byte unitType = null;
                if (unitLevel == DeptConstants.UNIT_LEVEL_7) {
                    unitType = physicalUnitImportTemplate.getUnitType();
                    if (Objects.isNull(unitType)) {
                        throw new IllegalArgumentException("单元等级为7时,单元类型必须在小区/街道/自然庄中选择一个");
                    }
                }
                String ancestor = null;
                Byte type = null;
                Long parentId = null;

                //探针单元
                WbPhysicalUnit probeWbPhysicalUnit = new WbPhysicalUnit();
                switch (unitLevel) {
                    case 6:
                        /*//获取六级单元的爷爷单元
                        SysDept unit4 = sysDeptService.selectDeptById(lastLastUnitId);
                        if (Objects.isNull(unit4)) {
                            throw new IllegalArgumentException("上上级单元ID不正确");
                        }

                        //获取六级单元的父亲单元
                        SysDept unit5 = new SysDept();
                        unit5.setParentId(unit4.getDeptId());
                        unit5.setDeptName(lastUnitName);
                        List<SysDept> unit5List = sysDeptService.selectDeptList(unit5);
                        if (unit5List.size() != 1) {
                            throw new IllegalArgumentException("上级单元名称不唯一");
                        }
                        unit5 = unit5List.get(0);*/

                        SysDept unit5 = sysDeptService.selectDeptById(lastLastUnitId);

                        //检测六级单元下是否已经存在同名单元
                        probeWbPhysicalUnit.setParentId(unit5.getDeptId());
                        probeWbPhysicalUnit.setName(unitName);
                        boolean isUnitExisted = this.checkWbPhysicalUnitExisted(probeWbPhysicalUnit);
                        if (!isUnitExisted) {
                            throw new IllegalArgumentException("上级单元名称下已经存在");
                        }

                        //设置祖先id
                        ancestor = unit5.getAncestors() + "," + unit5.getDeptId();
                        type = unit5.getType();
                        parentId = unit5.getDeptId();
                        break;
                    case 7:
                        //获取七级单元的爷爷单元
                        unit5 = sysDeptService.selectDeptById(lastLastUnitId);
                        if (Objects.isNull(unit5)) {
                            throw new IllegalArgumentException("上上级单元ID不正确");
                        }

                        //获取七级单元的父亲单元
                        WbPhysicalUnit unit6 = new WbPhysicalUnit();
                        unit6.setParentId(unit5.getDeptId());
                        unit6.setName(lastUnitName);
                        List<WbPhysicalUnit> unit6List = this.selectWbPhysicalUnit(unit6);
                        if (unit6List.size() != 1) {
                            throw new IllegalArgumentException("上级单元名称不唯一");
                        }
                        unit6 = unit6List.get(0);

                        //检测七级单元下是否已经存在同名单元
                        probeWbPhysicalUnit.setParentId(unit6.getId());
                        probeWbPhysicalUnit.setName(unitName);
                        isUnitExisted = this.checkWbPhysicalUnitExisted(probeWbPhysicalUnit);
                        if (!isUnitExisted) {
                            throw new IllegalArgumentException("上级单元名称下已经存在:");
                        }

                        //设置祖先id
                        ancestor = unit6.getAncestors() + "," + unit6.getId();
                        type = unit6.getType();
                        parentId = unit6.getId();
                        break;
                    case 8:
                    case 9:
                        //获取爷爷单元
                        WbPhysicalUnit grandFatherUnit = this.selectByPrimaryKey(lastLastUnitId);
                        if (Objects.isNull(grandFatherUnit)) {
                            throw new IllegalArgumentException("上上级单元ID不正确");
                        }

                        //获取父亲单元
                        WbPhysicalUnit fatherUnit = new WbPhysicalUnit();
                        fatherUnit.setParentId(grandFatherUnit.getId());
                        fatherUnit.setName(lastUnitName);
                        List<WbPhysicalUnit> fatherUnitList = this.selectWbPhysicalUnit(fatherUnit);
                        if (fatherUnitList.size() != 1) {
                            throw new IllegalArgumentException("上级单元名称不唯一");
                        }
                        fatherUnit = fatherUnitList.get(0);

                        //检测该单元名称是否已经存在
                        probeWbPhysicalUnit.setParentId(fatherUnit.getId());
                        probeWbPhysicalUnit.setName(unitName);
                        isUnitExisted = this.checkWbPhysicalUnitExisted(probeWbPhysicalUnit);
                        if (!isUnitExisted) {
                            throw new IllegalArgumentException("上级单元名称下已经存在:");
                        }

                        ancestor = fatherUnit.getAncestors() + "," + fatherUnit.getId();
                        type = fatherUnit.getType();
                        parentId = fatherUnit.getId();
                        break;
                    default:
                        break;
                }
                WbPhysicalUnit wbPhysicalUnit = new WbPhysicalUnit();
                wbPhysicalUnit.setUnit7Type(unitType);
                wbPhysicalUnit.setName(unitName);
                wbPhysicalUnit.setAncestors(ancestor);
                wbPhysicalUnit.setLevel(unitLevel);
                wbPhysicalUnit.setType(type);
                wbPhysicalUnit.setParentId(parentId);
                this.insertWbPhysicalUnit(wbPhysicalUnit);
                successNum++;
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、部门" + physicalUnitImportTemplate.toString() + " 导入失败：";
                failureMsg.append(msg).append(e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new BusinessException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条");
        }
        return successMsg.toString();
    }

    @Override
    public boolean checkWbPhysicalUnitExisted(WbPhysicalUnit wbPhysicalUnit) {
        List<WbPhysicalUnit> tempUnitList = selectWbPhysicalUnit(wbPhysicalUnit);
        return tempUnitList.isEmpty();
    }
}
